package com.erlang4j.example.swingClient;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

import com.ericsson.otp.erlang.OtpErlangPid;
import com.erlang4j.api.Erlang4jFactory;
import com.erlang4j.api.IErlang4j;
import com.erlang4j.api.IGetData;
import com.erlang4j.api.adapters.SwingMessageAdapter;
import com.erlang4j.api.process.IProcess;
import com.erlang4j.api.process.IProcessWithState;

/**
 * This implements a simple panel with a text area showing data sent from the server and a text field at the bottom that
 * you type into and sends data to the server The erlang code to support this is: <br>
 * <br>
 * start() -> register(swingClientServer, spawn(fun() -> loop() end)). <br>
 * <br>
 * loop() -> <br>
 * &nbsp;&nbsp;&nbsp;receive<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{Pid,{text,Text}}-><br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;io:format("text: ~p~n", [Text]),<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pid!{self(),{display,Text}},<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loop();<br>
 * &nbsp;&nbsp;&nbsp;Any -><br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;io:format("Message: ~p~n", [Any]),<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loop()<br>
 * &nbsp;&nbsp;&nbsp;end.<br>
 * 
 * @author phil.rice
 */
public class SwingClientPanel implements IHasComponent {

	private final JPanel panel = new JPanel(new BorderLayout());
	private final JTextArea results = new JTextArea(8, 40);
	private final JTextField userEntry = new JTextField();
	private final IProcess process;

	public SwingClientPanel(final IErlang4j erlang4J, final String serverName) {
		results.setEditable(false);
		panel.add(new JScrollPane(results), BorderLayout.CENTER);
		panel.add(userEntry, BorderLayout.SOUTH);

process = erlang4J.spawn(new SwingMessageAdapter("{Pid,{display,String}}") {
	@Override
	public void process(IProcessWithState process, IGetData data) throws Exception {
		results.append(data.getString("String") + "\n");
		results.setCaretPosition(results.getText().length());
	}
});
userEntry.addActionListener(new ActionListener() {
	@Override
	public void actionPerformed(ActionEvent e) {
		process.send(serverName, "{Self,{text,P0}}", userEntry.getText());
		userEntry.setText("");
	}
});
	}

	private OtpErlangPid getSelf() {
		return process.self();
	}

	@Override
	public JComponent getComponent() {
		return panel;
	}

	public static void main(String[] args) throws Exception {
		IErlang4j erlang4j = Erlang4jFactory.make("ErlangVm", "cookie");
		for (int i = 0; i < 3; i++)
			makeAndShowFrame(erlang4j, i);
	}

	private static void makeAndShowFrame(final IErlang4j erlang4j, final int i) throws InterruptedException, InvocationTargetException {
		SwingUtilities.invokeAndWait(new Runnable() {
			public void run() {
				JFrame frame = new JFrame();
				frame.setLocation(i * 50, i * 50);
				SwingClientPanel client = new SwingClientPanel(erlang4j, "simpleServer");
				OtpErlangPid pid = client.getSelf();
				frame.setTitle(pid.toString());
				frame.add(client.getComponent());
				frame.pack();
				frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
				frame.setVisible(true);
			}
		});

	}

}

/*
 * The Erlang code that needs to run on the ErlangVm is:
 * 
 * 
 * -module(swingClientServer).
 * 
 * -export([start/0]).
 * 
 * start() -> register(swingClientServer, spawn(fun() -> loop() end)).
 * 
 * loop() -> receive {Pid,{text,Text}}-> io:format("text: ~p~n", [Text]), Pid!{self(),{display,Text}}, loop(); Any ->
 * io:format("Message: ~p~n", [Any]), loop() end.
 */

